package main

import (
	"fmt"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jinzhu/gorm"
)

// 官网地址：http://v1.gorm.io/docs/query.html

type User struct {
	// binding: "required" 修饰的字段是必须字段，若接收到的为***零值***(即使为整型0也不行)，则报错，如果确实有零值，转换为指针(或使用scanner/valuer)即可
	// ****** 成员首字母必须大写 ******
	Uid      string
	Name     string    `gorm:"default:'lxd'"`
	Age      *uint8    `gorm:"default:18"`
	Birthday time.Time `gorm:"default:null;"`
}

// 创建记录之前的钩子
func (user *User) BeforeCreate(scope *gorm.Scope) error {
	// scope.SetColumn("ID", uuid.New())
	scope.SetColumn("ID", time.Now().Local().Second())
	return nil
}

func main() {

	db, err := gorm.Open("mysql", "root:Liuxd.4719@(39.108.60.51:3306)/gorm_sty?charset=utf8mb4&parseTime=True&loc=Local")
	if err != nil {
		panic(err)
	}
	defer db.Close()

	// Migrate the schema 创建数据表
	execAndPrintErrLog(db.AutoMigrate(&User{}), nil)

	// createRecord(db)

	// query(db)
}

func execAndPrintErrLog(db *gorm.DB, v interface{}) {
	if err := db.Error; err != nil {
		fmt.Println(err.Error())
	} else {
		fmt.Printf("%#v\n", v)
	}
}

func createRecord(db *gorm.DB) {
	age := uint8(18)
	user := User{Name: "liuxd", Age: &age, Birthday: time.Now()}

	fmt.Println(db.NewRecord(user)) // => returns `true` as primary key is blank
	execAndPrintErrLog(db.Create(&user), user)
	fmt.Println(db.NewRecord(user)) // => return `false` after `user` created

	user = User{Name: "demo", Birthday: time.Now()}
	fmt.Println(db.NewRecord(user)) // => returns `true` as primary key is blank
	execAndPrintErrLog(db.Create(&user), user)
	fmt.Println(db.NewRecord(user)) // => return `false` after `user` created
}

func query(db *gorm.DB) {
	user := User{}
	// users := []User{}
	users := make([]User, 1)
	// Get first record, order by primary key
	execAndPrintErrLog(db.First(&user), user)
	//// SELECT * FROM users ORDER BY id LIMIT 1;

	// Get one record, no specified order
	execAndPrintErrLog(db.Take(&user), user)
	//// SELECT * FROM users LIMIT 1;

	// Get last record, order by primary key
	execAndPrintErrLog(db.Last(&user), user)
	//// SELECT * FROM users ORDER BY id DESC LIMIT 1;

	// Get all records
	execAndPrintErrLog(db.Find(&users), users)
	//// SELECT * FROM users;

	// Get record with primary key (only works for integer primary key)
	execAndPrintErrLog(db.First(&user, 10), users)
	//// SELECT * FROM users WHERE id = 10;
}
